package com.lifeonwalden.copula.util;

import java.util.List;

public interface ArrayUtil {
    static int[] fetchIndexOfAscOrder(double[] array) {
        int[] ascOrderIndex = new int[array.length];
        int[] queue = new int[array.length];
        for (int i = 0; i < array.length; i++) {
            queue[i] = i;
        }

        int remainder = queue.length;
        for (int i = 0; i < array.length; i++) {
            int cursor = queue[0];
            int targetIdx;
            for (int k = 1; k < remainder; k++) {
                targetIdx = queue[k];

                if (array[cursor] > array[targetIdx]) {
                    queue[k - 1] = cursor;
                    cursor = targetIdx;
                } else {
                    queue[k - 1] = targetIdx;
                }
            }
            ascOrderIndex[i] = cursor;
            remainder--;
        }

        return ascOrderIndex;
    }

    static int[] fetchIndexOfAscOrder(int[] array) {
        int[] ascOrderIndex = new int[array.length];
        int[] queue = new int[array.length];
        for (int i = 0; i < array.length; i++) {
            queue[i] = i;
        }

        int remainder = queue.length;
        for (int i = 0; i < array.length; i++) {
            int cursor = queue[0];
            int targetIdx;
            for (int k = 1; k < remainder; k++) {
                targetIdx = queue[k];

                if (array[cursor] > array[targetIdx]) {
                    queue[k - 1] = cursor;
                    cursor = targetIdx;
                } else {
                    queue[k - 1] = targetIdx;
                }
            }
            ascOrderIndex[i] = cursor;
            remainder--;
        }

        return ascOrderIndex;
    }

    static <T extends Comparable<T>> int[] fetchIndexOfAscOrder(T[] array) {
        int[] ascOrderIndex = new int[array.length];
        int[] queue = new int[array.length];
        for (int i = 0; i < array.length; i++) {
            queue[i] = i;
        }

        int remainder = queue.length;
        for (int i = 0; i < array.length; i++) {
            int cursor = queue[0];
            int targetIdx;
            for (int k = 1; k < remainder; k++) {
                targetIdx = queue[k];

                if (array[cursor].compareTo(array[targetIdx]) > 0) {
                    queue[k - 1] = cursor;
                    cursor = targetIdx;
                } else {
                    queue[k - 1] = targetIdx;
                }
            }
            ascOrderIndex[i] = cursor;
            remainder--;
        }

        return ascOrderIndex;
    }

    static <T extends Comparable<T>> int[] fetchIndexOfAscOrder(List<T> array) {
        int[] ascOrderIndex = new int[array.size()];
        int[] queue = new int[array.size()];
        for (int i = 0; i < array.size(); i++) {
            queue[i] = i;
        }

        int remainder = queue.length;
        for (int i = 0; i < array.size(); i++) {
            int cursor = queue[0];
            int targetIdx;
            for (int k = 1; k < remainder; k++) {
                targetIdx = queue[k];

                if (array.get(cursor).compareTo(array.get(targetIdx)) > 0) {
                    queue[k - 1] = cursor;
                    cursor = targetIdx;
                } else {
                    queue[k - 1] = targetIdx;
                }
            }
            ascOrderIndex[i] = cursor;
            remainder--;
        }

        return ascOrderIndex;
    }
}
